/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
/*
-----------------------------------------------------------------------------
Filename:    ExampleFrameListener.h
Description: Defines an example frame listener which responds to frame events.
This frame listener just moves a specified camera around based on
keyboard and mouse movements.
Mouse:    Freelook
W or Up:  Forward
S or Down:Backward
A:        Step left
D:        Step right
PgUp:     Move upwards
PgDown:   Move downwards
F:        Toggle frame rate stats on/off
R:        Render mode
T:        Cycle texture filtering
Bilinear, Trilinear, Anisotropic(8)
P:        Toggle on/off display of camera position / orientation
-----------------------------------------------------------------------------
*/

#ifndef __SAFrameListener_H__
#define __SAFrameListener_H__
#include <Ogre.h>
#include "library/SharePtr.h"
#include <Hikari.h>
SHARE_PTR(Hikari::HikariManager, HikariManager)

//Use this define to signify OIS will be used as a DLL
//(so that dll import/export macros are in effect)
#define OIS_DYNAMIC_LIB
#include <OIS/OIS.h>
#include <SDKTrays.h>
#include "GUIInteractive.h"
#include <OgreSceneQuery.h>
#include <OgreSceneManager.h>
#include <map>
#include <string>
SHARE_PTR(OgreBites::SdkTrayManager, SdkTrayManager)
SHARE_PTR(OgreBites::SdkTrayListener, SdkTrayListener)

struct Event
{
	std::string name;
	int id;
};

class SAFrameListener: public Ogre::FrameListener, public Ogre::WindowEventListener
{
public:
	enum GUI_EVENT
	{
		BuildTrack = 1,
		BuildTrain,
		TrainView,
		FreeView,
		TopView,
		Linear,
		BSprine,
		HSprine,
		Bezier,
		Line,
		Road
	};
	typedef std::map<std::string, int> strmap;
	// Constructor takes a RenderWindow because it uses that to determine input context
	SAFrameListener(Ogre::SceneManager* _SceneMgr, Ogre::RenderWindow* win, Ogre::Camera* cam, HikariManager_Sptr hikariMgr, bool bufferedKeys = false, bool bufferedMouse = false,
		bool bufferedJoy = false );
	//Adjust mouse clipping area
	virtual void windowResized(Ogre::RenderWindow* rw);
	//Unattach OIS before window shutdown (very important under Linux)
	virtual void windowClosed(Ogre::RenderWindow* rw);
	virtual ~SAFrameListener();
	virtual bool processUnbufferedKeyInput(const Ogre::FrameEvent& evt);
	virtual bool processUnbufferedMouseInput(const Ogre::FrameEvent& evt);
	virtual void moveCamera();
	// Override frameRenderingQueued event to process that (don't care about frameEnded)
	bool frameRenderingQueued(const Ogre::FrameEvent& evt);
	bool frameEnded(const Ogre::FrameEvent& evt);
	OIS::Mouse*	getMouse(){return mMouse;}
	bool		getMouseDown(int i=0);
	Ogre::Ray	getMouseRay();
	Ogre::Vector2	getMousePos();
	void UpdateRayTracing();
	bool IsShutDown(){return m_ShutDown;}
	bool			m_ShutDown;
	Ogre::RaySceneQuery*	m_RayScnQuery;
	// flash eventGetGuiEvent
	Hikari::FlashValue FlCall_GetGuiEvent(Hikari::FlashControl* caller, const Hikari::Arguments& args);
protected:
	Hikari::FlashControl*	m_FlashControl;
	strmap			m_eventmap;
	friend	GUIInteractive;
	GUIInteractive*		m_GUIInteractive;
	char			m_mousekey[3];	
	HikariManager_Sptr	m_hikariMgr;
	SdkTrayManager_Sptr	m_TrayMgr;
	SdkTrayListener_Sptr	m_SdkTrayListener;
	OgreBites::ParamsPanel*	m_DetailsPanel;
	Ogre::SceneManager*	m_SceneMgr;
	Ogre::Camera*		mCamera;
	Ogre::Vector3 mTranslateVector;
	Ogre::Real mCurrentSpeed;
	Ogre::RenderWindow* mWindow;
	bool mStatsOn;
	std::string mDebugText;
	unsigned int mNumScreenShots;
	float mMoveScale;
	float mSpeedLimit;
	Ogre::Degree mRotScale;
	// just to stop toggles flipping too fast
	Ogre::Real mTimeUntilNextToggle ;
	Ogre::Radian mRotX, mRotY;
	Ogre::TextureFilterOptions mFiltering;
	int mAniso;
	int mSceneDetailIndex ;
	Ogre::Real mMoveSpeed;
	Ogre::Degree mRotateSpeed;
	//OIS Input devices
	OIS::InputManager* mInputManager;
	OIS::Mouse*    mMouse;
	OIS::Keyboard* mKeyboard;
	OIS::JoyStick* mJoy;
};
#endif
